/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package neuronalenetzeelearning.model;

import java.util.Vector;

/**
 * Idee: Es muss das Wortpaar K1-K2 gelernt werden. Ist die Verbindung zw. K1 und
 * K2 so stark, dass Nach dem Feuern von K1 auch K2 immer feuert, so hat der
 * neuronale Verband gelernt.
 * @author Maria
 */
public class HebbLearningRule extends LearningRule {

    double[] eingabe;

    public HebbLearningRule(Graph graph, double learningRate, StepFunction stepFunction) {
        super(graph, learningRate, stepFunction);
    }

    public HebbLearningRule(Graph graph, double learningRate, StepFunction stepFunction, Vector<Vector<Double>> IV) {
        super(graph, learningRate, stepFunction, IV);
    }

// double deltaWi_j =LearningRule.getLearningRate()  *Node.getThreshold()  * getWeight();
    /** Hebb-Lernregel(Graph graph){
     * Veränderung des Wertes der Gewichtsmatrix an der Stelle i,j  =lernrate           *(aktivierungswert des empfangenen Neurons) *(ausgang des sendenden Nerons)
     * }
     * Gewicht Zeitpkt t+1 = Gewicht Zeitpkt t + Lernrate*(ausgang des sendenden Nerons - Gewicht Zeitpkt t)
     */
//    @Override
    /**
     * Teta: Lernrate --> LearningRule.getLearningRate()
     * a_j: Aktivierungswert des empfangenen Neurons: getThreshold()
     * o_i: Ausgang des sendenden Neurons:graph.getLayer1Nodes().getOutputValue
     * Veränderung im Graphen:
     * es muss für jede kante berechnet werden wie sich ihr Gewicht ändert
     * @see Eingabevector bestimmen!!!
     */
    @Override
    public void nextStep() {
        super.setRandomInput();
        double wi_j = 0;
        //rechne alle outputValues von L1(abhängig von der Aktivierungsfkt.), lege sie in ausgabe ab
       
        //gehe alle Knoten der 2. Schicht durch
        for (int i = 0; i < getGraph().getLayer2Nodes().size(); i++) {
            double summe = 0;
            Node node = getGraph().getLayer2Nodes().get(i);
            //geht über die eingehenden Kanten
            for (int j = 0; j < node.getIncomingEdges().size(); j++) {
                // rechnet mit dem L1 Knoten. 
                double ausgang = getGraph().getEdges().get(j).getFrom().getOutputValue();
                // ausgang des vorgänger-neurons über die kante j
                double o_i = ausgang;
//                double o_i = node.getIncomingEdges().get(j).getFrom().getOutputValue();
                //aktueller Wert der Kante
                wi_j = node.getIncomingEdges().get(j).getWeight();
                //neuer Wert der Kante
                wi_j = wi_j + getLearningRate() * (o_i - wi_j);
                //
                node.getIncomingEdges().get(j).setWeight(wi_j);
                //Kantengewicht der kante wi_j
                summe = summe + wi_j;
            }
            //aktivierung des knoten j
        }
    }
//rausnehmen

    @Override
    /*
     * Hat zZ keine Nutzung
     */
    public void getChangeWeight(Graph graph) {
        nextStep();
    }

    @Override
    /*
     * Wird in den Klassen LearningRule & PropertyController durch die Methode
     * RestrictedLearningIteration realisiert
     */
    public void nextStep(int anzahlDerWiederholungen) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
